﻿#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include "SFML/Graphics.h"

typedef unsigned char	uint8;
typedef char			sint8;
typedef unsigned short	uint16;
typedef short			sint16;
typedef unsigned int	uint32;
typedef int				sint32;

#define MAP_WIDE 10 // 地图横向像素个数
#define MAP_HIGH 10 // 地图纵向像素个数
#define PIXEL_SIZE 20 //初始化像素大小
#define SNAKE_SIZE 3 //蛇的初始大小
#define SEED (uint32)time(NULL)// 将现在的时间作为种子
#define EGG 68//触发彩蛋长度

sfColor LOVE_COLOR = { 255, 182, 193, 255 };

//女士商务
sfColor SCREEN_COLOR = { 245, 245, 245, 255 };
sfColor HEAD_COLOR = { 255, 105, 180, 255 };
sfColor TAIL_COLOR = { 255, 182, 193, 255 };
sfColor FOOD_COLOR = { 0, 173, 239, 255 };

static uint8 UpPressed = 0;// 上方向键状态
static uint8 LeftPressed = 0;// 左方向键状态
static uint8 DownPressed = 0;// 下方向键状态
static uint8 RightPressed = 0;// 右方向键状态

static uint8 Up_Pressed = 0;// 上方向键状态
static uint8 Left_Pressed = 0;// 左方向键状态
static uint8 Down_Pressed = 0;// 下方向键状态
static uint8 Right_Pressed = 0;// 右方向键状态

static uint8 Add_Pressed = 0;// 下方向键状态
static uint8 Red_Pressed = 0;// 右方向键状态

static uint8 Color_Pressed = 0;// 主题切换键状态

enum Direction {
	Up,
	Left,
	Down,
	Right
};

typedef struct {
	uint8 x;
	uint8 y;
	uint8 MovingDir; // 方向枚举
} SnakePlayer;

typedef struct {
	uint8 x;
	uint8 y;
} Food;

typedef struct {
	uint8 x;
	uint8 y;
} SnakeTail;

static uint8 cycleRate = 10; // 周期长度（越小越快）
static uint8 cycleRate_Normal = 10;
static uint8 cycleRate_Boost = 2;
static uint32 cycleCount = 0; // 每帧递增一次
static uint8 b_isPaused = 0;

static SnakePlayer player = { MAP_WIDE / 2, MAP_HIGH / 2, Right };
static SnakeTail tail[MAP_WIDE * MAP_HIGH];
static uint16 tailIndex = 0; // 蛇的当前长度
static uint8 b_hasMoved = 0; // 防止蛇做 180 度转弯
static Food food1, food2;
static Food love_food[10];
static unsigned int screen_position_x = 0;
static unsigned int screen_position_y = 0;
static unsigned int screen_scaling = 0;
static unsigned int screen_color = 0;

// 渲染变量
static sfImage* map; // 3种可能的值（空、蛇、食物）
static sfTexture* texture;
static sfSprite* sprite;

static void addTail() {
	// 当尾部索引指向空元素时
	if (tailIndex == MAP_WIDE * MAP_HIGH) return;
	tail[tailIndex] = (SnakeTail){ tail[tailIndex - 1].x, tail[tailIndex - 1].y };
	tailIndex++;
}

static void shiftTails() {
	for (uint16 i = 0; i < tailIndex; i++) {
		uint16 index = tailIndex - i - 1; // 从最后的尾部到0

		if (index == 0) {
			tail[index] = (SnakeTail){ player.x, player.y };
		}
		else {
			tail[index] = (SnakeTail){ tail[index - 1].x,  tail[index - 1].y };
		}
	}
}

static void food_randomLocation(Food* p_food) {
	p_food->x = rand() % MAP_WIDE;
	p_food->y = rand() % MAP_HIGH;
}

static void food_LoveLocation(Food p_food[]) {
	p_food[0] = (Food){ 0,0 };
}

static void food_checkIfOnSnake(Food* p_food) {
	for (uint16 i = 0; i < tailIndex; i++) {
		if (p_food->x == tail[i].x && p_food->y == tail[i].y) {
			food_randomLocation(p_food);
			addTail();
		}
	}
}

static void Restart() {
	player = (SnakePlayer){ MAP_WIDE / 2,MAP_HIGH / 2 ,Right };// 设置玩家初始位置和方向
	tailIndex = 0; // 尾巴的长度
	cycleCount = 0;

	// 设置前6个蛇尾
	for (uint8 i = 0; i < SNAKE_SIZE; i++) {
		if (i == 0) {
			tail[i] = (SnakeTail){ player.x, player.y };
		}
		else {
			tail[i] = (SnakeTail){ player.x - i, player.y };
		}
		tailIndex++;
	}

	food_randomLocation(&food1); // 设置食物位置
	food_randomLocation(&food2); // 设置食物位置
}

static void snake_checkIfTouchedTail() {
	for (uint16 i = 1; i < tailIndex; i++) {
		if (tail[i].x == player.x && tail[i].y == player.y) {
			Restart();
			return;
		}
	}
}

void Game_Setup() {
	map = sfImage_create(MAP_WIDE, MAP_HIGH);// 创建图像
	texture = sfTexture_create(MAP_WIDE, MAP_HIGH);// 创建纹理
	sprite = sfSprite_create();// 创建精灵
	sfSprite_setTexture(sprite, texture, sfFalse);//将指定纹理给到指定精灵上

	srand(SEED); // 设置随机数生成器种子
	Restart();// 重新开始
}

void Game_Draw(sfRenderWindow* window) {
	if (b_isPaused) return; // 游戏暂停时不执行任何操作

	// 每个周期更新玩家位置
	if (cycleCount % cycleRate == 0) {
		switch (player.MovingDir)
		{
		case Up:
			player.y--;
			break;
		case Left:
			player.x--;
			break;
		case Down:
			player.y++;
			break;
		case Right:
			player.x++;
			break;
		}

		// 当蛇超出边界时，将其移到另一侧
		if (player.x == 0xFF) player.x = MAP_WIDE - 1;
		if (player.y == 0xFF) player.y = MAP_HIGH - 1;
		if (player.x == MAP_WIDE) player.x = 0;
		if (player.y == MAP_HIGH) player.y = 0;

		b_hasMoved = 1; // 允许输入函数更改蛇的方向
		shiftTails(); // 玩家移动后，移动蛇尾
		(void)rand(); // 随机化食物位置以供后用

		// 碰撞检测
		snake_checkIfTouchedTail();// 检测蛇头与蛇尾碰撞
		food_checkIfOnSnake(&food1);// 检测蛇是否吃到食物
		food_checkIfOnSnake(&food2);
	}
	cycleCount++;

	// 清空屏幕
	for (uint8 y = 0; y < MAP_HIGH; y++) {
		for (uint8 x = 0; x < MAP_WIDE; x++) {
			sfImage_setPixel(map, x, y, SCREEN_COLOR);
		}
	}

	// 绘制玩家
	sfImage_setPixel(map, player.x, player.y, HEAD_COLOR);

	// 绘制蛇尾
	for (uint16 i = 0; i < tailIndex; i++) {
		if (i != 0) {
			sfImage_setPixel(map, tail[i].x, tail[i].y, TAIL_COLOR);
		}
	}

	// 绘制食物
	sfImage_setPixel(map, food1.x, food1.y, FOOD_COLOR);
	sfImage_setPixel(map, food2.x, food2.y, FOOD_COLOR);

	sfTexture_updateFromImage(texture, map, 0, 0);// 更新纹理
	sfRenderWindow_drawSprite(window, sprite, NULL);// 绘制精灵
}

void Love_Draw(sfRenderWindow* window) {
	if (b_isPaused) return; // 游戏暂停时不执行任何操作

	// 清空屏幕
	for (uint8 y = 0; y < MAP_HIGH; y++) {
		for (uint8 x = 0; x < MAP_WIDE; x++) {
			sfImage_setPixel(map, x, y, SCREEN_COLOR);
		}
	}
	for (int i = 0; i < MAP_HIGH; i++) {
		for (int j = 0; j < MAP_WIDE; j++) {
			if (i == 0 && j >= 2 && j <= 5)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 1 && j >= 1 && j <= 6)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 2 && j >= 0 && j <= 7)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 3 && j >= 1 && j <= 8)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 4 && j >= 2 && j <= 9)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 5 && j >= 2 && j <= 9)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 6 && j >= 1 && j <= 8)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 7 && j >= 0 && j <= 7)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 8 && j >= 1 && j <= 6)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
			if (i == 9 && j >= 2 && j <= 5)
				sfImage_setPixel(map, i, j, LOVE_COLOR);
		}
	}
	sfTexture_updateFromImage(texture, map, 0, 0);// 更新纹理
	sfRenderWindow_drawSprite(window, sprite, NULL);// 绘制精灵
}

void Game_Input(sfEvent* event) {

	// 当鼠标按下时加速蛇移动
	if (event->type == sfEvtMouseButtonPressed) {
		if (event->mouseButton.button == sfMouseLeft) cycleRate = cycleRate_Boost;
	}
	if (event->type == sfEvtMouseButtonReleased) {
		if (event->mouseButton.button == sfMouseLeft) cycleRate = cycleRate_Normal;
	}

	// 当空格键按下时暂停/继续游戏
	if (event->type == sfEvtKeyPressed) {
		if (event->key.code == sfKeySpace) b_isPaused = !b_isPaused;
	}


	// 移动方向键
	if (event->type == sfEvtKeyPressed) {
		if (!b_hasMoved) return; // 如果不允许改变蛇的方向，则退出函数
		b_hasMoved = 0;

		// 重置方向键状态
		UpPressed = 0;
		LeftPressed = 0;
		DownPressed = 0;
		RightPressed = 0;

		// 检查特定的按键是否按下
		switch (event->key.code)
		{
		case sfKeyW:
			UpPressed = 1;
			break;
		case sfKeyA:
			LeftPressed = 1;
			break;
		case sfKeyS:
			DownPressed = 1;
			break;
		case sfKeyD:
			RightPressed = 1;
			break;
		case sfKeyLeft:
			Left_Pressed = 1;
			break;
		case sfKeyRight:
			Right_Pressed = 1;
			break;
		case sfKeyUp:
			Up_Pressed = 1;
			break;
		case sfKeyDown:
			Down_Pressed = 1;
			break;
		case sfKeyEqual:
			Add_Pressed = 1;
			break;
		case sfKeyHyphen:
			Red_Pressed = 1;
			break;
		case sfKeyC:
			Color_Pressed = 1;
			break;
		}
	}
	if (event->type == sfEvtKeyReleased) {
		// 检查特定的按键是否抬起
		switch (event->key.code) {
		case sfKeyLeft:
			Left_Pressed = 0;
			break;
		case sfKeyRight:
			Right_Pressed = 0;
			break;
		case sfKeyUp:
			Up_Pressed = 0;
			break;
		case sfKeyDown:
			Down_Pressed = 0;
			break;
		case sfKeyEqual:
			Add_Pressed = 0;
			break;
		case sfKeyHyphen:
			Red_Pressed = 0;
			break;
		}
	}

	// 仅允许蛇在当前面朝的方向上转向
	switch (player.MovingDir)
	{
	case Up:
		if (LeftPressed) player.MovingDir = Left;
		if (RightPressed) player.MovingDir = Right;
		break;
	case Left:
		if (DownPressed) player.MovingDir = Down;
		if (UpPressed) player.MovingDir = Up;
		break;
	case Down:
		if (RightPressed) player.MovingDir = Right;
		if (LeftPressed) player.MovingDir = Left;
		break;
	case Right:
		if (UpPressed) player.MovingDir = Up;
		if (DownPressed) player.MovingDir = Down;
		break;
	}
}

void Game_Destroy() {
	sfTexture_destroy(texture);
	sfSprite_destroy(sprite);
}

int value_limit(int value, int min, int max) {
	if (value <= min) {
		value = min;
	}
	else if (value >= max) {
		value = max;
	}
	return value;
}

void move_window(sfRenderWindow* window) {
	// 设置窗口位置
	if (Up_Pressed == 1)
		screen_position_y -= 10;
	if (Left_Pressed == 1)
		screen_position_x -= 10;
	if (Down_Pressed == 1)
		screen_position_y += 10;
	if (Right_Pressed == 1)
		screen_position_x += 10;
	sfRenderWindow_setPosition(window, (sfVector2i) 
	{ value_limit(screen_position_x,0, GetSystemMetrics(SM_CXSCREEN)- MAP_WIDE * screen_scaling), value_limit(screen_position_y, 0, GetSystemMetrics(SM_CYSCREEN)-MAP_HIGH* screen_scaling)});
}

void scaling_window(sfRenderWindow* window) {
	if (Add_Pressed == 1)
		screen_scaling += 1;
	if (Red_Pressed == 1)
		screen_scaling -= 1;
	int x = 0;
	int y = 0;
	x = value_limit(MAP_WIDE * screen_scaling,10, GetSystemMetrics(SM_CXSCREEN));
	y = value_limit(MAP_HIGH * screen_scaling, 10, GetSystemMetrics(SM_CYSCREEN));
	sfRenderWindow_setSize(window, (sfVector2u) 
	{ x, y});
}

void color_window(sfRenderWindow* window) {
	if (Color_Pressed == 1){
		screen_color += 1;
		if (screen_color >= 7)
			screen_color = 0;
	}
	Color_Pressed = 0;
	switch (screen_color) {
	case 0://女士商务
		SCREEN_COLOR = (sfColor){ 245, 245, 245, 255 };
		HEAD_COLOR = (sfColor){ 255, 105, 180, 255 };
		TAIL_COLOR = (sfColor){ 255, 182, 193, 255 };
		FOOD_COLOR = (sfColor){ 0, 173, 239, 255 };
		LOVE_COLOR = TAIL_COLOR;
		break;
	case 1:// 翠绿色主题
		SCREEN_COLOR = (sfColor) { 52, 73, 94, 255 };
		HEAD_COLOR = (sfColor)   { 46, 204, 113, 255 };
		TAIL_COLOR = (sfColor)   { 39, 174, 96, 255 };
		FOOD_COLOR = (sfColor)   { 231, 76, 60, 255 };
		LOVE_COLOR = FOOD_COLOR;
		break;
	case 2:// 紫色主题
		SCREEN_COLOR = (sfColor){ 23, 32, 42, 255 };
		HEAD_COLOR = (sfColor){ 230, 126, 34, 255 };
		TAIL_COLOR = (sfColor){ 155, 89, 182, 255 };
		FOOD_COLOR = (sfColor){ 231, 76, 60, 255 };
		LOVE_COLOR = FOOD_COLOR;
		break;
	case 3:// 红色主题
		SCREEN_COLOR = (sfColor){ 35, 39, 65, 255 };
		HEAD_COLOR = (sfColor){ 241, 196, 15, 255 };
		TAIL_COLOR = (sfColor){ 192, 57, 43, 255 };
		FOOD_COLOR = (sfColor){ 46, 204, 113, 255 };
		LOVE_COLOR = FOOD_COLOR;
		break;
	case 4:// 粉色主题
		SCREEN_COLOR = (sfColor){ 255, 240, 245, 255 };
		HEAD_COLOR = (sfColor){ 255, 105, 180, 255 };
		TAIL_COLOR = (sfColor){ 147, 112, 219, 255 };
		FOOD_COLOR = (sfColor){ 255, 182, 193, 255 };
		LOVE_COLOR = FOOD_COLOR;
		break;
	case 5:// 活力主题
		SCREEN_COLOR = (sfColor){ 54, 73, 93, 255 };
		HEAD_COLOR = (sfColor){ 255, 165, 0, 255 };
		TAIL_COLOR = (sfColor){ 46, 139, 87, 255 };
		FOOD_COLOR = (sfColor){ 255, 0, 0, 255 };
		LOVE_COLOR = FOOD_COLOR;
		break;
	case 6://高级商务
		SCREEN_COLOR = (sfColor){ 20, 20, 20, 255 };
		HEAD_COLOR = (sfColor){ 0, 135, 200, 255 };
		TAIL_COLOR = (sfColor){ 150, 150, 150, 255 };
		FOOD_COLOR = (sfColor){ 200, 50, 50, 255 };
		LOVE_COLOR = FOOD_COLOR;
		break;
	}
}

int main() {
	// 创建窗口和视图
	sfRenderWindow* window = sfRenderWindow_create((sfVideoMode) { MAP_WIDE* PIXEL_SIZE, MAP_HIGH* PIXEL_SIZE }, "Snake", sfNone, NULL);
	sfView* view = sfView_create();
	screen_position_x = 0;
	screen_position_y = (GetSystemMetrics(SM_CYSCREEN) / 5) * 4;
	screen_scaling = PIXEL_SIZE;
	// 设置视图大小
	sfView_setCenter(view, (sfVector2f) { MAP_WIDE / 2, MAP_HIGH / 2 });
	sfView_setSize(view, (sfVector2f) { MAP_WIDE, MAP_HIGH });

	// 设置窗口位置
	sfRenderWindow_setPosition(window, (sfVector2i) { screen_position_x, screen_position_y });

	sfRenderWindow_setFramerateLimit(window, 60);// 设置窗口帧率
	sfRenderWindow_setView(window, view);// 在窗口中作用视图
	sfRenderWindow_setKeyRepeatEnabled(window, sfFalse);// 关闭按键按下重复触发

	// 初始化
	Game_Setup();

	while (sfRenderWindow_isOpen(window)) {
		sfEvent event;
		while (sfRenderWindow_pollEvent(window, &event)) {

			// 键盘输入
			Game_Input(&event);
			if (event.type == sfEvtClosed) {
				sfRenderWindow_close(window);
			}
			else if (event.type == sfEvtKeyPressed) {
				if (event.key.code == sfKeyEscape) {
					sfRenderWindow_close(window);
				}
			}
		}

		// 渲染/更新
		if (tailIndex <= EGG)
			Game_Draw(window);
		else {
			Love_Draw(window);
			if (b_isPaused == 1) 
				Restart();
		}
		move_window(window);
		scaling_window(window);
		color_window(window);
		/*sfVector2i windowPosition = sfRenderWindow_getPosition(window);
		windowPosition = sfRenderWindow_getPosition(window);
		printf("Window position: (%d, %d)\n", windowPosition.x, windowPosition.y);*/
		sfRenderWindow_display(window);
		
	}

	// 游戏结束
	Game_Destroy();
	sfView_destroy(view);
	sfRenderWindow_destroy(window);
	return 0;
}
